﻿using System;
using System.IO;
using System.Reflection;
using System.Text;
using RpcHelper;

namespace CLIHelper.Model
{
        internal class AssemblyBody
        {
                private readonly Assembly _Assembly;
                public AssemblyBody (Assembly assembly)
                {
                        this._Assembly = assembly;
                }
                private string _Namespace;
                private ApiServiceBody[] _Services;
                private string _RootName;
                public void Init ()
                {
                        Type[] types = this._Assembly.GetTypes ();
                        types = types.FindAll (a => a.IsClass && ( a.GetCustomAttribute (ConstDic._IConfigType) != null || a.GetCustomAttribute (ConstDic._IBroadcastType) != null ) && a.BaseType != ConstDic._objectType);
                        if (types.Length == 0)
                        {
                                return;
                        }
                        string name = this._Assembly.GetName ().Name;
                        _RootName = Helper.Helper.GetRootName (name);
                        this._Namespace = Helper.Helper.GetNamespace (name);
                        string[] names = types.Distinct (a => a.Namespace);
                        this._Services = names.ConvertAll (a =>
                        {
                                Type[] t = types.FindAll (c => c.Namespace == a);
                                string sName = Helper.Helper.FormatNamespace (a, name, _RootName);
                                ApiServiceBody body = new ApiServiceBody (sName, this._Namespace, _RootName);
                                body.Init (t);
                                return body;
                        });

                }

                public void Save (DirectoryInfo dir, FileInfo source)
                {
                        if (!dir.Exists)
                        {
                                dir.Create ();
                        }
                        string path = Path.Combine (dir.FullName, "Reference");
                        DirectoryInfo reDir = new DirectoryInfo (path);
                        if (!reDir.Exists)
                        {
                                reDir.Create ();
                        }
                        string toPath = Path.Combine (path, source.Name);
                        if (!File.Exists (toPath))
                        {
                                source.CopyTo (toPath);
                        }
                        string dllDir = Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "Reference");
                        if (Directory.Exists (dllDir))
                        {
                                Helper.Helper.CopDir (new DirectoryInfo (dllDir), reDir);
                        }
                        string caspDir = Path.Combine (dir.FullName, this._Namespace);
                        dir = new DirectoryInfo (caspDir);
                        if (dir.Exists)
                        {
                                dir.Delete ();
                        }
                        dir.Create ();
                        string csproj = Path.Combine (dir.FullName, string.Concat (this._Namespace, ".csproj"));
                        string casprojVal = string.Format (ConstDic.CsprojTemplate, source.Name, this._Namespace);
                        Tools.WriteText (csproj, casprojVal, Encoding.UTF8);
                        DirectoryInfo serviceDir = dir.CreateSubdirectory ("Services");
                        DirectoryInfo interDir = dir.CreateSubdirectory ("Interface");
                        this._Services.ForEach (a =>
                        {
                                a.Save (serviceDir, interDir);
                        });
                        DirectoryInfo apiDir = dir.CreateSubdirectory ("Api");
                        DirectoryInfo mode = dir.CreateSubdirectory ("Model");
                        this._Services.ForEach (a =>
                        {
                                ApiGatewayBody api = new ApiGatewayBody (a);
                                api.Save (apiDir, mode);
                        });
                        GatewayConfigModel.Save (this._Namespace, dir, _RootName);
                }

        }
}
